<template>
  <div class="page-content">
    <deviceInfo ref="deviceInfo" style="margin-bottom: 12px" />
    <div class="title-detail text-center font-size-18 text-bold">
      {{ $utils.label(workshop.label) }}{{getLineName()}}
    </div>
    <div class="title flex justify-between items-center" style="margin-top: -34px;margin-bottom: 10px">
      <div>
        当前班制：{{shifts.name}}
        <span v-if="shifts.name.length" class="small-title">({{shifts.startTime}}—{{shifts.endTime}})</span>
        <span>{{shifts.workFlagName}}</span>
      </div>
      <div class="text-right">
        <table-btn @click="selWorkshop" icon="icontubiao-74" btn-type="other" tooltip="车间选择"/>
      </div>
    </div>
    <div class="flex justify-between margin-b-20">
      <div class="form-inline" style="padding: 0">
        <select-tooltip v-model="line"
                        isShowAll
                        :multiple='false'
                        :options="lineList"
                        @changeData="getShiftsDate"
                        msg="产线选择"/>
      </div>
      <legend-list :hasCraft="hasCraft" :hasWork="hasWork"/>
    </div>
    <div class="flex-1 content-container scroll-y scrollbar">
      <div class="row items-center justify-between margin-b-24">
        <div class="flex column col-8">
          <workshop ref="workshop" class="margin-b-24" :count-map="countMap" :hasCraft="hasCraft" :hasWork="hasWork"/>
          <div class="flex justify-between">
            <div style="width: 49%">
              <shift ref="shift" :hasCraft="hasCraft" :hasWork="hasWork"/>
            </div>
            <div style="width: 49%">
              <availability ref="availability"/>
            </div>
          </div>
        </div>
        <div class="flex column padding-l-24 col-4" style="height: 708px">
          <job ref="job" class="margin-b-24" v-if="hasPermission"/>
          <ranking ref="ranking" :has-permission="hasPermission" :style="{'height': hasPermission ? 'calc(100% - 328px)' : '100%'}"/>
        </div>
      </div>
      <div class="row items-start justify-between">
        <div class="col-6" style="padding-right: 12px">
          <stop-rate ref="stopRate"/>
        </div>
        <div class="col-6" style="padding-left: 12px">
          <alarm-rate ref="alarmRate"/>
        </div>
      </div>
    </div>
    <sel-workshop :workshop-list="workshopList" ref="selWorkshop" @changeSel="changeSel"/>
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex'
import workshop from './components/status-overview/workshop-real-time'
import shift from './components/status-overview/shift-real-time'
import job from './components/status-overview/job-real-time'
import ranking from './components/status-overview/ranking-list'
import selWorkshop from './components/status-overview/sel-workshop'
import legendList from './components/legend'
import stopRate from './components/status-overview/stop-rate'
import alarmRate from './components/status-overview/alarm-rate'
import deviceInfo from 'src/pages/home/components/home/device-info'
import availability from 'src/pages/home/components/home/availability'
import {
  getWorkshops,
  getShifts,
  getLinesByWorkshop,
  getCountDevice,
  getRealtimeStatus
} from 'src/boot/status-monitor/status-overview'
import { getShiftsDate } from 'src/boot/home/home-new'
import _ from 'lodash'
import moment from 'moment'
import roleMenuApi from 'src/boot/system/role-menu'
moment.locale('zh-cn')
export default {
  name: 'status-overview',
  components: {
    selWorkshop,
    legendList,
    workshop,
    shift,
    job,
    ranking,
    stopRate,
    alarmRate,
    deviceInfo,
    availability
  },
  data () {
    return {
      shifts: {
        name: '',
        id: '',
        startTime: '',
        endTime: '',
        workFlag: 0
      },
      countMap: {
        total: 0,
        networking: 0
      },
      isInit: true, // 页面初始化
      line: 'all',
      lineList: [],
      workshopList: [], // 车间list
      workshop: {}, // 所选车间
      stopNotWrite: [],
      // 实时状态
      realTimeStatus: {
        process: 0, // 加工
        stop: 0, // 停机
        breaks: 0, // 断开
        offLine: 0, // 离线
        alert: 0, // 报警
        changeLine: 0, // 换线
        fault: 0, // 故障
        repair: 0 // 维修
      },
      timer: null, // 定时器
      // 缓存实时状态数据
      realTimeStatusData: [],
      hasPermission: false, // 生产模块权限
      hasCraft: false, // 生产模块权限
      hasWork: false // shebei
    }
  },
  beforeDestroy () {
    // 清除定时器
    clearTimeout(this.timer)
    this.timer = null
    // 取消订阅
    this.closeUbscribeTopic()
  },
  beforeRouteEnter (to, from, next) {
    next(vm => {
      vm.saveCustomerSet()
      vm.isInit && vm.hasCraftMenu()
      !vm.isInit && vm.getShiftsDate()
    })
  },
  beforeRouteLeave (to, from, next) {
    // 清除定时器
    clearTimeout(this.timer)
    this.timer = null
    // 取消订阅
    this.closeUbscribeTopic()
    next()
  },
  computed: {
    ...mapGetters(['permissions', 'client', 'userInfo'])
  },
  watch: {
    permissions () {
      let self = this
      this.getSelData()
      window.onresize = () => {
        return (() => {
          self.barChart.resize()
          self.lineChart.resize()
        })()
      }
    }
  },
  methods: {
    hasCraftMenu () {
      this.$q.loading.show()
      // 从状态中获取租户Id
      const tenantId = this.userInfo.tenant_id
      // 获取租户所购买的所有系统视图
      roleMenuApi.getCompanyView(tenantId, 'pc').then(res => {
        this.hasPermission = _.indexOf(res.data, this.Enums.SYS_PERMISSION.CRAFT_MENU.value) !== -1
        this.hasCraft = _.indexOf(res.data, this.Enums.SYS_PERMISSION.CRAFT_MENU.value) !== -1
        this.hasWork = _.indexOf(res.data, this.Enums.SYS_PERMISSION.WORK_MENU.value) !== -1
      }).finally(() => {
        this.getSelData()
      })
    },
    getSelData () {
      getWorkshops().then(res => {
        this.workshopList = res.data
        if (res.data.length) {
          if (this.isInit) {
            this.isInit = false
            this.workshop = res.data[0]
          }
          this.onSubscribe()
          this.getShiftsDate()
          this.getLineList()
        } else {
          this.$q.loading.hide()
          this.$message.warning('请先在“基础数据-工厂建模”里创建车间！')
        }
      }).finally(() => {
        this.$q.loading.hide()
      })
    },
    // 获取当前班制日期
    getShiftsDate () {
      getShiftsDate(this.workshop.value).then(res => {
        if (res) {
          this.getShifts(res)
          this.$refs.deviceInfo.getData()
          this.$refs.availability.changeWorkshop(this.workshop.value)
        } else {
          this.$message.warning('请先在“基础数据-工厂日历”里设置班制！')
          this.removeData()
        }
      }).catch(() => {
        this.removeData()
      })
    },
    // 获取班制
    getShifts (date) {
      this.$q.loading.show()
      this.removeData()
      getShifts(this.workshop.value).then(res => {
        if (res.data) {
          this.shifts = _.cloneDeep(res.data)

          this.shifts.startTime = this.getTime(res.data.startTime)
          this.shifts.endTime = this.getTime(res.data.endTime)
          this.shifts.name = this.$utils.label(res.data.name, '')

          const workLabel = ['休息中', '工作中', '换班中', '休息日', '未排班']
          this.shifts.workFlagName = this.$utils.label(workLabel[res.data.workFlag || 0])
          if (this.shifts.startTime && this.shifts.endTime) {
            this.$q.loading.hide()
            // 有班制时间请求当班数据
            this.getData(this.getDateTime(this.shifts, date), date, res.data.id)
          }
          // 实时不受班制时间限制
          this.getRealData()
        }
      }).finally(() => {
        // 5分钟定时
        this.timer = setTimeout(() => {
          this.getShiftsDate()
        }, 300000)
        this.$q.loading.hide()
      })
    },
    getRealData () {
      this.$nextTick(() => {
        this.$refs.workshop.showLoading()
        let params = {}
        this.line !== 'all' && (params['lineId'] = this.line)
        this.line === 'all' && (params['workshopId'] = this.workshop.value)
        getCountDevice(params).then(res => {
          this.countMap = {
            total: this.$utils.label(res.allDeviceCount),
            networking: this.$utils.label(res.connectDeviceCount)
          }
        }).finally(() => {
          this.getRealtimeStatus(params)
        })
      })
    },
    getRealtimeStatus (params) {
      getRealtimeStatus(params).then(res => {
        this.realTimeStatusData = res
        this.realTimeStatus = this.initRealTimeStatus(res)
        this.$refs.workshop.getInfo(this.realTimeStatus)
      })
    },

    // 重构实时状态分布
    initRealTimeStatus (info) {
      let realTimeStatus = {
        process: 0, // 加工
        stop: 0, // 停机
        breaks: 0, // 断开
        offLine: 0, // 离线
        alert: 0, // 报警
        changeLine: 0, // 换线
        fault: 0, // 故障
        repair: 0 // 维修
      }

      for (let key in info) {
        _.indexOf(info[key], 0) !== -1 && (++realTimeStatus.stop)
        _.indexOf(info[key], 1) !== -1 && (++realTimeStatus.process)
        _.indexOf(info[key], 51) !== -1 && (++realTimeStatus.process)
        _.indexOf(info[key], 2) !== -1 && (++realTimeStatus.offLine)
        _.indexOf(info[key], 3) !== -1 && (++realTimeStatus.breaks)
        _.indexOf(info[key], 4) !== -1 && (++realTimeStatus.alert)
        _.indexOf(info[key], 5) !== -1 && (++realTimeStatus.changeLine)
        _.indexOf(info[key], 6) !== -1 && (++realTimeStatus.fault)
        _.indexOf(info[key], 7) !== -1 && (++realTimeStatus.repair)
      }
      return realTimeStatus
    },
    // 获取当班实时的数据
    getData (time, shiftDate, shiftId) {
      // 获取当班设备开动率
      this.$nextTick(() => {
        this.$refs.shift.getStatus(time, this.workshop.value, this.line)
        this.hasPermission && this.$refs.job.getData(this.workshop.value, this.line)
        this.$refs.ranking.initRankTableData({
          ...time,
          shiftId: this.shifts.id
        }, this.workshop.value, this.line)
        this.$refs.stopRate.getStopChart({
          ...time,
          shiftDate,
          shiftId
        }, this.workshop.value, this.line)
        this.$refs.alarmRate.getAlarmChart(time, this.workshop.value, this.line)
      })
    },
    // 根据时分获取日期时间
    getDateTime (shift = _.cloneDeep(this.shifts), date) {
      let dateObj = {}
      if (date) {
        const dateArr = _.split(date, '-')
        dateObj = {
          year: dateArr[0],
          month: dateArr[1] - 1, // moment月份需-1
          date: dateArr[2]
        }
      }
      let startArr = _.split(shift.startTime, ':')
      let startDateTime = moment().set({ ...dateObj, hours: Number(startArr[0]), minutes: Number(startArr[1]), seconds: 0 })

      let endArr = _.split(shift.endTime, ':', 2)
      let endDateTime = moment().set({ ...dateObj, hours: Number(endArr[0]), minutes: Number(endArr[1]), seconds: 0 })

      shift.isStartTimeOnNextDay && startDateTime.add(1, 'd')
      shift.isEndTimeOnNextDay && endDateTime.add(1, 'd')

      const params = {
        start: startDateTime.format('YYYY-MM-DDTHH:mm:ss'),
        end: endDateTime.format('YYYY-MM-DDTHH:mm:ss')
      }
      return params
    },
    // 获取产线
    getLineList () {
      this.line = 'all'
      getLinesByWorkshop(this.workshop.value).then(res => {
        let lineList = []
        if (res.length) {
          lineList = res.map(item => {
            return {
              value: item.id,
              label: item.name
            }
          })
        }
        this.lineList = lineList
        this.line = 'all'
      })
    },
    // 获取时间
    getTime (time) {
      let label = ''
      if (time) {
        let timeArr = time.split(':')

        label = timeArr[0] + ':' + timeArr[1]
      }
      return label
    },
    // 清空数据
    removeData () {
      // 清除定时器
      clearTimeout(this.timer)
      this.timer = null
      const realTimeStatus = {
        process: 0, // 加工
        stop: 0, // 停机
        breaks: 0, // 断开
        offLine: 0, // 离线
        alert: 0, // 报警
        changeLine: 0, // 换线
        fault: 0, // 故障
        repair: 0 // 维修
      }
      this.countMap = {
        total: 0,
        networking: 0
      }
      this.$refs.workshop.getInfo(realTimeStatus)
      this.$refs.shift.clearData()
      this.hasPermission && this.$refs.job.clearData()
      this.$refs.ranking.clearData()
      this.$refs.stopRate.clearData()
      this.$refs.alarmRate.clearData()
    },
    selWorkshop () {
      this.$refs.selWorkshop.showDialog(this.workshop)
    },
    // 修改所选车间车间
    changeSel (workshop) {
      if (workshop.value !== this.workshop.value) {
        this.oldPlantId = this.workshop.value
        this.workshop = JSON.parse(JSON.stringify(workshop))
        this.line = 'all'
        this.getShiftsDate()
        this.getLineList()
        this.onSubscribe()
      }
    },
    // 订阅消息
    onSubscribe () {
      if (this.client) {
        this.closeUbscribeTopic()
        this.client.subscribe(`${this.CommonConfig.socketConfig.SOCKET_TOPIC.realTimeStatus.subscribeTopic}${this.workshop.value}`, this.onMessageArrived, { id: this.workshop.value })
      } else {
        setTimeout(() => {
          this.onSubscribe()
        }, 200)
      }
    },
    /**
     * 接受盒子返回消息
     * @param {string} message
     */
    onMessageArrived (message) {
      let data = JSON.parse(message.body).data
      // 实时状态分布
      if (this.realTimeStatusData[data.deviceId]) {
        let statusArr = _.cloneDeep(this.realTimeStatusData[data.deviceId])
        let newStatus = []
        switch (data.statusCode) {
          // 判断是否是报警相关
          case 4:
            // 报警时
            if (data.alarmCount) {
              // 如果存在4，就保持原状
              if (_.indexOf(statusArr, 4) === -1) {
                // 在倒数第二位插入4
                newStatus = _.concat(statusArr, data.statusCode)
              } else {
                newStatus = statusArr
              }
            } else {
              // 报警解除时，去掉4
              newStatus = statusArr.filter(item => item !== 4)
            }
            break
          // 换线结束，去掉5
          case 51:
            if (data.statusCode === 51) {
              newStatus = statusArr.filter(item => item !== 5)
            }
            break
          // 换线
          case 5:
            // 状态添加
            if (_.indexOf(statusArr, data.statusCode) === -1) {
              newStatus = _.concat(statusArr, data.statusCode)
            } else {
              newStatus = statusArr
            }
            break
          // 故障、维修
          case 6:
          case 7:
            if (data.overFlag) {
              // 状态解除，去掉对应的错误码
              newStatus = statusArr.filter(item => item !== data.statusCode)
            } else {
              // 状态添加
              if (_.indexOf(statusArr, data.statusCode) === -1) {
                newStatus = _.concat(statusArr, data.statusCode)
              } else {
                newStatus = statusArr
              }
            }
            break
          // 其他状态修改最后一位
          default:
            const statusList = [0, 1, 2, 3]
            const newArr = statusArr.filter(item => _.indexOf(statusList, item) === -1)
            // 状态添加
            newStatus = _.concat(newArr, data.statusCode)
            break
        }
        this.$set(this.realTimeStatusData, data.deviceId, newStatus)
        const realTimeStatus = this.initRealTimeStatus(this.realTimeStatusData)
        this.realTimeStatus = realTimeStatus
        this.$refs.workshop.getInfo(realTimeStatus)
      }
    },
    /**
     * 取消订阅
     */
    closeUbscribeTopic () {
      if (this.oldPlantId) {
        this.client.unsubscribe(this.oldPlantId)
      }
    },
    // 获取产线名
    getLineName () {
      const label = this.line === 'all' ? '' : '-' + this.lineList.find(item => item.value === this.line).label
      return label
    },
    ...mapActions([
      'getWebScoket',
      'saveCustomerSet'
    ])
  }
}
</script>

<style scoped lang="stylus">
  .padding-l-24{
    padding-left 24px
  }
  .margin-b-24{
    margin-bottom 24px
  }
  .content-container{
    margin-right -24px
    padding-right 24px
  }
    >>>.select-tooltip{
      label{
        margin 0 !important
        .q-field__control{
          background-color #fff !important
        }
      }
    }
</style>
